package com.dataextend.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dataextend.dto.ActMissionDTO;
import com.dataextend.dto.PropertyAndActDTO;
import com.dataextend.dto.RegularMissionDTO;
import com.dataextend.entity.MarketListRequest;
import com.dataextend.mapper.cluster.MarketMapper;
import com.dataextend.mapper.master.ClickhouseMapper;
import com.dataextend.utils.DateUtils;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 *  推送消息列表
 */
@Slf4j
@Service
public class MarketListService {
    @Autowired
    MarketMapper marketMapper;
    @Autowired
    ClickhouseMapper clickhouseMapper;



    /** 行为触发-列表页 */
    public JSONObject actMissionList(String name, Integer status, Integer pageno, Integer pagesize) {
        Integer pageNo = (pageno - 1) * pagesize;
        Integer pageSize = pagesize;
        List<JSONObject> returnResult = new ArrayList<>();
        List<JSONObject> originResult = marketMapper.actMissionList(name, status, pageNo, pageSize);
        List<JSONObject> statusInfos = marketMapper.actMissionStatusInfo();
        List<JSONObject> statusInfo = new ArrayList<>();
        Integer[] statusEnums = {0,1,2};
        for (Integer i :statusEnums) {
            int flag=0;
            for (JSONObject info : statusInfos) {
                if (i.equals(info.getInteger("status"))) {
                    statusInfo.add(info);
                    flag=1;
                }
            }
            if (flag==0){
                JSONObject detail = new JSONObject(true);
                detail.put("status", i);
                detail.put("num", 0);
                statusInfo.add(detail);
            }
        }

        Integer num = marketMapper.actMissionListCount(name, status);
        for (JSONObject obj : originResult) {
            JSONObject detail = new JSONObject(true);
            detail.put("missionId", obj.getString("mission_id"));
            detail.put("missionName", obj.getString("mission_name"));
            detail.put("introduction", obj.getString("introduction"));
            detail.put("createTime", obj.getString("create_time"));
            detail.put("creator", obj.getString("creator"));
            detail.put("status", obj.getInteger("status"));
            Gson gson1 = new GsonBuilder().disableHtmlEscaping().create();
            ActMissionDTO.actJudgeInfo actJudge = gson1.fromJson(obj.getString("act_judge"), new TypeToken<ActMissionDTO.actJudgeInfo>(){}.getType());
            detail.put("actJudge", actJudge);

            Gson gson2 = new GsonBuilder().disableHtmlEscaping().create();
            ActMissionDTO.propertyJudgeInfo propertyJudgeInfo = gson2.fromJson(obj.getString("property_judge"), new TypeToken<ActMissionDTO.propertyJudgeInfo>(){}.getType());
            detail.put("propertyJudge", propertyJudgeInfo);

            Gson gson3 = new GsonBuilder().disableHtmlEscaping().create();
            ActMissionDTO.blacklistFilterInfo blacklistFilter = gson3.fromJson(obj.getString("blacklist_filter"), new TypeToken<ActMissionDTO.blacklistFilterInfo>(){}.getType());
            detail.put("blacklistFilter", blacklistFilter);

            Gson gson4 = new GsonBuilder().disableHtmlEscaping().create();
            ActMissionDTO.waitFilterInfo waitFilter = gson4.fromJson(obj.getString("wait_filter"), new TypeToken<ActMissionDTO.waitFilterInfo>(){}.getType());
            detail.put("waitFilter", waitFilter);

            Gson gson5 = new GsonBuilder().disableHtmlEscaping().create();
            ActMissionDTO.putChannelInfo putChannel = gson5.fromJson(obj.getString("pub_channel"), new TypeToken<ActMissionDTO.putChannelInfo>(){}.getType());
            detail.put("putChannel", putChannel);

            Gson gson6 = new GsonBuilder().disableHtmlEscaping().create();
            List<ActMissionDTO.sequenceInfo> sequencesInfo = gson6.fromJson(obj.getString("sequence"), new TypeToken<List<ActMissionDTO.sequenceInfo>>(){}.getType());
            detail.put("sequence", sequencesInfo);

            String operationPeriod = actJudge.getStartDate() + "至" + actJudge.getEndDate();
            detail.put("operationPeriod", operationPeriod);
            returnResult.add(detail);
        }
        JSONObject result = new JSONObject(true);
        result.put("list", returnResult);
        result.put("status", statusInfo);
        result.put("num", num);
        return result;
    }


    /** 定时任务-活动分析 */
    public JSONObject regularMissionAnalysis(String missionid) {
        List<JSONObject> details = clickhouseMapper.regularMissionAnalysis(missionid);
        List<Integer> sendNumList = new ArrayList<>();
        List<Integer> clickNumList = new ArrayList<>();
        for (JSONObject detail :details) {
            sendNumList.add(Integer.valueOf(detail.getString("sendnum")));
            clickNumList.add(Integer.valueOf(detail.getString("clicknum")));
        }
        JSONObject result = new JSONObject(true);
        result.put("list", details);
        result.put("sendNum", sendNumList.stream().reduce(Integer::sum).orElse(0));
        result.put("clickNum", clickNumList.stream().reduce(Integer::sum).orElse(0));
        return result;
    }


    /** 行为触发-活动分析 */
    public JSONObject actMissionAnalysis(String missionid) {
        List<JSONObject> details = clickhouseMapper.actMissionAnalysis(missionid);
        List<Integer> sendNumList = new ArrayList<>();
        for (JSONObject detail :details) {
            sendNumList.add(Integer.valueOf(detail.getString("sendnum")));
        }
        JSONObject result = new JSONObject(true);
        result.put("list", details);
        result.put("sendNum", sendNumList.stream().reduce(Integer::sum).orElse(0));
        return result;
    }


    /** 投放渠道下拉菜单 */
    public List<String> channelList() {
        return marketMapper.channelList();
    }


    /** 行为触发-创建任务 */
    public void actMissionCreate(ActMissionDTO actMissionDTO) {
        String missionId = "";
        if (actMissionDTO.getMissionId() == null) {
            String maxGroupId = marketMapper.maxActMissionId();
            int id = 0;
            if (maxGroupId == null) {
                id = 0;
            } else {
                id = Integer.parseInt(maxGroupId.replace("act_mission_", ""));
            }
            missionId = "act_mission_" + String.format("%0" + 4+ "d", id+1);
            log.info(">>>>>missionId:" + missionId);
        } else {
            missionId = actMissionDTO.getMissionId();
        }

        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
        String actJudge = gson.toJson(actMissionDTO.getActJudge());
        String propertyJudge = gson.toJson(actMissionDTO.getPropertyJudge());
        String blacklistFilter = gson.toJson(actMissionDTO.getBlacklistFilter());
        String waitFilter = gson.toJson(actMissionDTO.getWaitFilter());
        String putChannel = gson.toJson(actMissionDTO.getPutChannel());
        String sequence = gson.toJson(actMissionDTO.getSequenceInfos());

        String createTime = DateUtils.getDateTime();
        marketMapper.actMissionCreate(missionId, actMissionDTO.getMissionName(), actMissionDTO.getIntroduction(),
                actJudge, propertyJudge, blacklistFilter, waitFilter, putChannel,createTime,sequence,"super", actMissionDTO.getStatus()
        );
    }



    /** 行为触发-获取任务id */
    public String actMissionGetid() {
        String maxGroupId = marketMapper.maxActMissionId();
        int id = 0;
        if (maxGroupId == null) {
            id = 0;
        } else {
            id = Integer.parseInt(maxGroupId.replace("act_mission_", ""));
        }
        String missionId = "act_mission_" + String.format("%0" + 4+ "d", id+1);
        return missionId;
    }


    /** 定时任务-人群筛选下拉菜单 */
    public List<JSONObject> regularUsergroupList(String name) {
        List<JSONObject> originResult = marketMapper.regularUsergroupList(name);
        List<JSONObject> returnResult = new ArrayList<>();
        for (JSONObject obj : originResult) {
            JSONObject detail = new JSONObject(true);
            detail.put("groupId", obj.getString("group_id"));
            detail.put("groupName", obj.getString("group_name"));
            detail.put("num", obj.getString("num"));
            detail.put("ruleType", obj.getString("rule_type"));
            Gson gson2 = new GsonBuilder().disableHtmlEscaping().create();
            PropertyAndActDTO.propertyRules property = gson2.fromJson(obj.getString("property_rules"), new TypeToken<PropertyAndActDTO.propertyRules>(){}.getType());
            detail.put("propertyRules", property);
            Gson gson3 = new GsonBuilder().disableHtmlEscaping().create();
            PropertyAndActDTO.actRules act = gson3.fromJson(obj.getString("act_rules"), new TypeToken<PropertyAndActDTO.actRules>(){}.getType());
            detail.put("actRules", act);
            returnResult.add(detail);
        }
        return returnResult;
    }


    /** 定时任务列表页 */
    public JSONObject regularMissionList(String name, Integer status, Integer pageno, Integer pagesize) {
        Integer pageNo = (pageno - 1) * pagesize;
        Integer pageSize = pagesize;
        List<JSONObject> returnResult = new ArrayList<>();
        List<JSONObject> originResult = marketMapper.regularMissionList(name, status, pageNo, pageSize);
        List<JSONObject> statusInfo = marketMapper.regularMissionStatusInfo();
        Integer num = marketMapper.regularMissionListCount(name, status);
        for (JSONObject obj : originResult) {
            JSONObject detail = new JSONObject(true);
            detail.put("missionId", obj.getString("mission_id"));
            detail.put("missionName", obj.getString("mission_name"));
            detail.put("groupId", obj.getString("groupid"));
            detail.put("messageTitle", obj.getString("message_title"));
            detail.put("messageContent", obj.getString("message_content"));
            detail.put("channel", obj.getString("channel"));
            Gson gson1 = new GsonBuilder().disableHtmlEscaping().create();
            RegularMissionDTO.ruleDetails sendRules =gson1.fromJson(obj.getString("send_rules"), new TypeToken<RegularMissionDTO.ruleDetails>(){}.getType());
            detail.put("sendRules", sendRules);
            Gson gson2 = new GsonBuilder().disableHtmlEscaping().create();
            PropertyAndActDTO.propertyRules property = gson2.fromJson(obj.getString("property_rules"), new TypeToken<PropertyAndActDTO.propertyRules>(){}.getType());
            detail.put("propertyRules", property);
            Gson gson3 = new GsonBuilder().disableHtmlEscaping().create();
            PropertyAndActDTO.actRules act = gson3.fromJson(obj.getString("act_rules"), new TypeToken<PropertyAndActDTO.actRules>(){}.getType());
            detail.put("actRules", act);
            detail.put("status", obj.getInteger("status"));
            detail.put("groupName", obj.getString("group_name"));
            detail.put("num", obj.getString("num"));
            detail.put("groupRuleType", obj.getString("rule_type"));
            detail.put("createTime", obj.getString("create_time"));
            detail.put("executeTime", obj.getString("execute_time"));
            detail.put("creator", obj.getString("creator"));
            String operationPeriod = "";
            if (sendRules.getPeriod().equals("仅发送一次")) {
                if (sendRules.getSendType().equals("立即发送")) {
                    operationPeriod = obj.getString("create_time");
                } else {
                    operationPeriod = sendRules.getBeginDate() + " " + sendRules.getSendTime();
                }
            } else {
                operationPeriod = sendRules.getBeginDate() + "至" + sendRules.getEndDate();
            }
            detail.put("operationPeriod", operationPeriod);

            log.info(">>>obj:" + obj);
            returnResult.add(detail);
        }
        JSONObject result = new JSONObject(true);
        result.put("list", returnResult);
        result.put("status", statusInfo);
        result.put("num", num);
        return result;
    }



    /** 创建定时任务 */
    public void createRegularMission(RegularMissionDTO regularMissionDTO) {
        String missionId = "";
        if (regularMissionDTO.getMissionId() == null) {
            String maxGroupId = marketMapper.maxMissionId();
            int id = 0;
            if (maxGroupId == null) {
                id = 0;
            } else {
                id = Integer.parseInt(maxGroupId.replace("regular_mission_", ""));
            }
            missionId = "regular_mission_" + String.format("%0" + 4+ "d", id+1);
            log.info(">>>>>missionId:" + missionId);
        } else {
            missionId = regularMissionDTO.getMissionId();
        }

        String createTime = DateUtils.getDateTime();
        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
        String rulesInfo = gson.toJson(regularMissionDTO.getSendRules());
        marketMapper.createRegularMission(missionId ,regularMissionDTO.getMissionName(), regularMissionDTO.getGroupId(),
                regularMissionDTO.getMessageTitle(), regularMissionDTO.getMessageContent(), regularMissionDTO.getChannel(),
                rulesInfo, regularMissionDTO.getStatus(), createTime, regularMissionDTO.getCreator());
    }


    /** 定时任务修改状态 */
    public void regularMissionChangeState(String missionId, Integer status) {
        switch (status) {
            case 0:
                marketMapper.regularMissionChangeState(missionId, status);
                break;
            case 1:
                marketMapper.regularMissionChangeState(missionId, status);
                break;
            case 2:
                marketMapper.regularMissionChangeState(missionId, status);
                break;
            case 3:
                marketMapper.regularMissionDelete(missionId);
                break;
        }
    }



    /** 行为触发-修改状态 */
    public void actMissionChangeState(String missionId, Integer status) {
        switch (status) {
            case 0:
                marketMapper.actMissionChangeState(missionId, status);
                break;
            case 1:
                marketMapper.actMissionChangeState(missionId, status);
                break;
            case 2:
                marketMapper.actMissionChangeState(missionId, status);
                break;
            case 3:
                marketMapper.actMissionDelete(missionId);
                break;
        }
    }






    public JSONObject marketList(MarketListRequest marketListRequest){
        List<JSONObject> returnInfo = new ArrayList<>();
        Integer total = 0;
        Integer pageNo = (marketListRequest.getPageNo() - 1) * marketListRequest.getPageSize();
        Integer pageSize = marketListRequest.getPageSize();
        if (marketListRequest.getMissionType().equals("邮件")){
            returnInfo = marketMapper.marketEmailList(marketListRequest.getMissionName(), pageNo, pageSize);
            total = marketMapper.marketEmailCount(marketListRequest.getMissionName());
        } else if (marketListRequest.getMissionType().equals("短信")){
            returnInfo = marketMapper.marketMessageList(marketListRequest.getMissionName(), pageNo, pageSize);
            total = marketMapper.marketMessageCount(marketListRequest.getMissionName());
        } else {
            returnInfo = marketMapper.marketPushList(marketListRequest.getMissionName(), pageNo, pageSize);
            total = marketMapper.marketPushCount(marketListRequest.getMissionName());
        }

        JSONObject result = new JSONObject();
        JSONArray returnDetail = new JSONArray();
        for (JSONObject obj : returnInfo){
            JSONObject detailInfo = new JSONObject(true);
            String missionName = obj.getString("mission_name");
            detailInfo.put("missionName", missionName);
            String groupID = obj.getString("group_id");
            detailInfo.put("groupId", groupID);
            String groupName = obj.getString("group_name");
            detailInfo.put("groupName", groupName);
            String creater = obj.getString("creater");
            detailInfo.put("creater", creater);
            String addTime = obj.getString("add_time");
            detailInfo.put("addTime", addTime);
            String pushTime = obj.getString("push_start_time");
            detailInfo.put("pushTime", pushTime);
            String targetNum = obj.getString("target_num");
            detailInfo.put("targetNum", targetNum);
            String sendNum = obj.getString("send_num");
            detailInfo.put("sendNum", sendNum);
            returnDetail.add(detailInfo);
        }

        result.put("list", returnDetail);
        result.put("total", total);

        return result;
    }
}
